package com.fsd.admin.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.fsd.core.common.BusinessException;
import com.fsd.core.util.Config;
import com.fsd.core.util.EhcacheUtil;
import com.fsd.core.util.ParametersUtil;
import com.fsd.admin.model.A_Employee;
import com.fsd.admin.model.Sys_SystemParameters;
import com.fsd.admin.service.Sys_SystemParametersService;
import com.fsd.admin.dao.Sys_SystemParametersDao;
import com.google.gson.Gson;

@Repository("Sys_SystemParametersServiceImpl")
public class Sys_SystemParametersServiceImpl extends MainServiceImpl<Sys_SystemParameters, String> implements Sys_SystemParametersService{

	private String depict = "系统参数";
	
    @Resource(name = "Sys_SystemParametersDaoImpl")
	public void setBaseDao(Sys_SystemParametersDao Sys_SystemParametersDao) {
		super.setBaseDao(Sys_SystemParametersDao);
	}
	
	@Resource(name = "Sys_SystemParametersDaoImpl")
	private Sys_SystemParametersDao objectDao;
	
	//----------------------------系统参数------------------------
		/**
		 * 系统项目加载选择菜单组
		 */
		public static final String SITEMENU = "FSDSITEMENU";
		/**
		 * 网站前台浏览器标签显示标题名称
		 */
		public static final String SITETITLE = "FSDSITETITLE";
		/**
		 * 网站管理平台浏览器标签显示标题名称
		 */
		public static final String SITEADMINTITLE = "FSDSITEADMIN";
		/**
		 * 网站管理平台顶部显示图标和标题名称
		 */
		public static final String SITELOGOTITLE = "FSDSITELOGOTITLE";
		/**
		 * 网站前台和后台浏览器Tab标签上显示图标
		 */
		public static final String SITELOGOICON = "FSDSITELOGOICON";
		/**
		 * 网站前台访问地址根路径
		 */
		public static final String SITEURL = "FSDSITEURL";
		/**
		 * 网站管理平台访问地址根路径
		 */
		public static final String SITEMANAGEURL = "FSDSITEMANAGEURL";
		/**
		 * 网站前台内容页访问地址根路径
		 */
		public static final String SITEARTICLEURL = "FSDSITEARTICLEURL";
		/**
		 * 密码过期时间
		 */
		public static final String PWDTIME = "FSDPWDTIME";
		/**
		 * 当前站点是否开启或关闭
		 */
		public static final String SITEENABLE = "FSDSITEENABLE";
		/**
		 * 任务计划是否开启或关闭
		 */
		public static final String JOBENABLE = "FSDJOBENABLE";
		/**
		 * 指定财务共享数据单位
		 */
		public static final String FINANCECOMPANY = "FSDFINANCECOMPANY";
		/**
		 * 指定会员管理微信公众号ApiID
		 */
		public static final String WECHATMEMBER = "FSDWECHATMEMBER";
	
	private static final Lock lock = new ReentrantLock();

	
	/**
	 * 刷新缓存信息
	 * @param companyid
	 */
	public void refreshEhcache(String companyid){
		EhcacheUtil.getInstance().remove(Config.PARAMETERMAP + companyid);
	}
	
	/**
	 * 获取系统参数集合
	 */
	private Map<String, Sys_SystemParameters> getObjectMap(String companyid) throws Exception{
		lock.lock();
		Map<String, Sys_SystemParameters> objectMap = null;
		String strKey = Config.PARAMETERMAP + companyid;
		try {
			if(EhcacheUtil.getInstance().get(strKey) == null){
				List<Sys_SystemParameters> allObjectList = objectDao.queryByHql(
						"from Sys_SystemParameters t where t.companyid = '" + companyid + "' order by t.code asc");
				objectMap = new HashMap<String, Sys_SystemParameters>();
				for (Sys_SystemParameters obj : allObjectList) {
					objectMap.put(obj.getCode(), obj);
				}
				EhcacheUtil.getInstance().put(strKey, objectMap);
			}else{
				objectMap = (Map<String, Sys_SystemParameters>)EhcacheUtil.getInstance().get(strKey);
			}
			return objectMap;
		} finally {
			lock.unlock();
		}
	}
	
	/**
	 * 获取系统参数信息，为Core工程提供相关功能模块的加载使用
	 */
	public Map<String, String> getParameterMapByCore(String companyid) throws Exception{
		Map<String, Sys_SystemParameters> objectMap = this.getObjectMap(companyid);
		if (objectMap == null)
			return null;
		Map<String, String> map = new HashMap<String, String>();
		for (String key : objectMap.keySet()) {
			map.put(key, objectMap.get(key).getValue());
		}
		return map;
	}
	
	/**
	 * 获取系统参数信息
	 */
	public String getParameterValueByCode(String code, String companyid) throws Exception{
		Map<String, Sys_SystemParameters> objectMap = this.getObjectMap(companyid);
		if (objectMap == null)
			return null;
		if (objectMap.containsKey(code)){
			return objectMap.get(code).getValue();
		}else{
			return null;
		}
	}
	
	/**
	 * 获取系统参数信息列表
	 */
	public List<Sys_SystemParameters> getParameterObjectListByCode(String code) throws Exception{
		Criteria c = objectDao.createCriteria();
		c.add(Restrictions.eq("code", code));
		c.addOrder(Order.asc("companyid"));
		return objectDao.getList(c);
	}
	
	/**
	 * 获取系统参数信息
	 */
	public String getParameterValueByCodeSql(String code, String companyid) throws Exception{
		List<Sys_SystemParameters> objectList = objectDao.queryByHql("from Sys_SystemParameters t where t.companyid = ? and code = ?", companyid, code);
		if (objectList == null){
			return null;
		}
		return objectList.get(0).getValue();
	}
	/**
	 * 获取系统参数信息
	 */
	public String getParameterValueByCodeSql(String code){
		List<Sys_SystemParameters> objectList = objectDao.queryByHql("from Sys_SystemParameters t where code = ?", code);
		if (objectList == null || objectList.size() == 0){
			return null;
		}
		return objectList.get(0).getValue();
	}
	
	/**
	 * 加载分页数据
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public ParametersUtil getObjectPageList(ParametersUtil param, A_Employee employee) throws Exception{
		Criteria c = objectDao.createCriteria();
		c.add(Restrictions.eq("companyid", employee.getCompanyid()));
		c.addOrder(Order.asc("code"));
		if(param.getJsonData() != null && !"".equals(param.getJsonData())){
			Gson gs = new Gson();
			Map objectMap = gs.fromJson(param.getJsonData(), Map.class);
			if(objectMap.get("name") != null && !"".equals(objectMap.get("name"))){
				c.add(Restrictions.like("name", "%" + objectMap.get("name") + "%"));
			}
		}
		return objectDao.findPager(param , c);
	}
	
	/**
	 * 加载所有数据
	 * @return
	 * @throws Exception
	 */
	public List<Sys_SystemParameters> getObjectList(A_Employee employee) throws Exception{
		return objectDao.queryByHql("from Sys_SystemParameters a where a.companyid = '"+ employee.getCompanyid() +"'");
	}
	
	/**
	 * 保存角色
	 * @throws Exception
	 */
	public void saveObject(Sys_SystemParameters obj, A_Employee employee) throws Exception{
		Sys_SystemParameters obj_old = objectDao.get(obj.getId());
		if(obj_old != null){
			//修改
			obj_old.setName(obj.getName());
			obj_old.setValue(obj.getValue());
			obj_old.setType(obj.getType());
			obj_old.setRemark(obj.getRemark());
			objectDao.update(obj_old);
		}else{
			//添加
			long num = objectDao.getCount("code = '"+ obj.getCode() +"'", "companyid = '"+ employee.getCompanyid() +"'");
			if (num > 0)
				throw new BusinessException(depict + obj.getCode() + "编码已经存在!");
			obj.setId(this.getUUID());//设置主键
			obj.setCompanyid(employee.getCompanyid());
			objectDao.save(obj);
		}
		EhcacheUtil.getInstance().remove(Config.PARAMETERMAP + employee.getCompanyid());
		this.sysLogService.saveObject(Config.LOGTYPEBC, this.depict + obj.getId() + obj.getName(), employee, Sys_SystemParametersServiceImpl.class);
	}
	
	/**
	 * 根据ID加载对象
	 * @param parameters
	 * @return
	 * @throws Exception
	 */
	public Sys_SystemParameters getObjectById(ParametersUtil parameters) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		if(objectMap.get("id") == null && "".equals(objectMap.get("id"))){
			throw new BusinessException(depict + "获取缺少ID参数!");
		}
		Sys_SystemParameters obj = objectDao.get(objectMap.get("id").toString());
		if(obj == null){
			throw new BusinessException(depict + "数据不存在!");
		}
		return obj;
	}
	
	/**
	 * 删除对象
	 * @param parameters
	 * @throws Exception
	 */
	public void delObject(ParametersUtil parameters) throws Exception{
		Gson gs = new Gson();
		Map objectMap = gs.fromJson(parameters.getJsonData(), Map.class);
		ArrayList<String> dir = (ArrayList<String>) objectMap.get("ids");
		for(int i=0;i<dir.size();i++){
			objectDao.delete(dir.get(i).toString());
		}
	}
	
	/**
	 * 修改参数值
	 * @param code
	 * @param value
	 * @param companyid
	 * @throws Exception
	 */
	public void updateObjectByValue(String code, String value, String companyid) throws Exception{
		objectDao.executeHql("update Sys_SystemParameters t set t.value = ? " +
				"where t.companyid = ? and code = ? ", value, companyid, code);
	}
	/**
	 * 修改参数值
	 * @param code
	 * @param value
	 * @throws Exception
	 */
	public void updateObjectByValue(String code, String value) throws Exception{
		objectDao.executeHql("update Sys_SystemParameters t set t.value = ? " +
				"where code = ? ", value, code);
	}
	
	/**
	 * 生成Excel文件
	 * @param url
	 * @throws Exception
	 */
	public void createExcel(List<Sys_SystemParameters> sysParameList, String url) throws Exception{
		WritableWorkbook book = Workbook.createWorkbook(new File(url)); //创建可写入的 Excel 工作薄
		WritableCellFormat format = new WritableCellFormat();
		WritableFont font = new WritableFont(WritableFont.ARIAL,16,WritableFont.BOLD); //字形
		format.setFont(font);
		format.setAlignment(Alignment.CENTRE);
		format.setVerticalAlignment(VerticalAlignment.CENTRE);
		format.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THIN);  //边框
		
		WritableCellFormat cellformat = new WritableCellFormat();
		cellformat.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THIN);
		cellformat.setWrap(true);  //设置单元格自适应列宽
		
		WritableCellFormat headerformat = new WritableCellFormat();
		WritableFont hFont = new WritableFont(WritableFont.ARIAL,WritableFont.DEFAULT_POINT_SIZE,WritableFont.BOLD); //字形加粗
		headerformat.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THIN);
		headerformat.setFont(hFont);
		
		WritableSheet sheet = book.createSheet("系统参数", 0);

		sheet.mergeCells(0,0,7,0); //a:最左上的列，b最左上的行，c最右下的列，d最右下的行 （合并单元格）
		sheet.getSettings().setDefaultColumnWidth(20);
		sheet.setColumnView(0,10);  //单独设置列宽 （0代表第几列，10代表宽度）
		Label label = new Label(0, 0, "系统参数", format);
		sheet.addCell(label);
		for (int i = 0; i < 8; i++) {
			Label label_tem = null;
			switch (i) {
			case 0:
				label_tem = new Label(i, 1, "",headerformat);
				break;
			case 1:
				label_tem = new Label(i, 1, "编号",headerformat);
				break;
			case 2:
				label_tem = new Label(i, 1, "所属单位",headerformat);
				break;
			case 3:
				label_tem = new Label(i, 1, "编码",headerformat);
				break;
			case 4:
				label_tem = new Label(i, 1, "类型",headerformat);
				break;
			case 5:
				label_tem = new Label(i, 1, "名称",headerformat);
				break;
			case 6:
				label_tem = new Label(i, 1, "值",headerformat);
				break;
			case 7:
				label_tem = new Label(i, 1, "备注",headerformat);
				break;
			default:
				break;
			}
			sheet.addCell(label_tem);
		}
		for (int j = 0; j < sysParameList.size(); j++){
			sheet.addCell(new Label(0,j+2, j+1+"",cellformat));
			sheet.addCell(new Label(1,j+2, sysParameList.get(j).getId(),cellformat));
			sheet.addCell(new Label(2,j+2, sysParameList.get(j).getCompanyid(),cellformat));
			sheet.addCell(new Label(3,j+2, sysParameList.get(j).getCode(),cellformat));
			sheet.addCell(new Label(4,j+2, sysParameList.get(j).getType(),cellformat));
			sheet.addCell(new Label(5,j+2, sysParameList.get(j).getName(),cellformat));
			sheet.addCell(new Label(6,j+2, sysParameList.get(j).getValue(),cellformat));
			sheet.addCell(new Label(7,j+2, sysParameList.get(j).getRemark(),cellformat));
		}
		book.write();
		book.close();
	}
	
	/**
	 * Excel导出
	 */
	public Map<String, String> download(A_Employee employee, String rootPath, String httpRootPath) throws Exception {
		List<Sys_SystemParameters> sysParameList = this.getObjectList(employee);
		String path = "uploadfiles/temp/"+UUID.randomUUID().toString().trim().replaceAll("-", "")+".xls";
		String url = rootPath+path;
		String httpUrl = httpRootPath+path;
		this.createExcel(sysParameList, url);
		Map<String, String> map = new HashMap<String, String>();
		map.put("httpUrl", httpUrl);
		return map;
	}
}
